Frontend.ctrl.categories = function() {
	var store = {

	// filter default option
	}, _filter = function(self) {
		var i = self,
			s = i.parent().find('span'),
			v = i.val();

		if(v.length > 0) s.hide();
		else s.fadeIn('fast');

	// bind for filter
	}, fields = function() {
		$('input[type="text"]', '#categories').each(function() {
			var self = $(this);

			_filter(self);
			self.on('input', function(){ _filter(self); });
		});

		$('select', '#categories').simpleselect();

	// on form submit intercept
	}, intercept = function() {
		// on query submit
		$('form#form_categories', '#categories').on('submit', function(e){
			e.preventDefault();

			// find disabled and enable them temporary for form
			var disabled = $(this).find(':input:disabled').removeAttr('disabled'),
				post = $(this).serialize(),
				b = $('button', '#form_categories');

			// disable them again
			disabled.attr('disabled', 'disabled');

			// for every form field
			$('input[type="text"]', '#form_categories').each(function() {
				var o = $(this);
					n = o.attr('name'),
					N = n.charAt(0).toUpperCase() + n.substr(1);

				// check if blank
				if(!$.trim(o.val()).length > 0) {
					Frontend.noty({type: 'error', text: N +' is blank'});
					o.addClass('error');
					o.val('');
					_filter(o);
				}
			});

			// check for errors
			var error = false;
			$('input[type="text"]', '#form_categories').each(function() {
				if($(this).hasClass('error'))
					error = true;
			});

			// stop if errors found
			if(error)
				return false;

			// do categories procedure
			b.attr('disabled', 'disabled');
			Frontend.ajax({type: 'post', data: post, url: 'categories/save', success: function(data){
				b.removeAttr('disabled');

				// send message
				Frontend.noty({type: 'success', text: 'Category was saved!'});

				// go to index
				Frontend.go('categories');
			}});
		});

	// bind events
	}, bind = function() {
		// on any input change, loose the error
		$('input[type="text"]', '#categories').on('input', function() {
			$(this).removeClass();
		});

		// on button click
		$('button', 'form.categories_handlers').on('click', function(e) {
			e.preventDefault();
			var b = $(this);

			// new category
			if(b.data('handle') == 'new')
				Frontend.go('categories/create');
		});

		// on sort
		$('div.sortable', '#categories').sortable({
			placeholder: "placeholder",
			distance: 15,
			cursor: 'move',
			update: function (event, ui) {
				// ajax data
				var data = {
					order: $(this).sortable("toArray").join("+_-+-_+").replace(new RegExp('cat_', 'g'), '').split('+_-+-_+')
				};

				// do ajax
				Frontend.ajax({type: 'post', data: data, url: 'categories/sort', success: function(data){
					// msg and spice
					Frontend.noty({type: 'success', text: 'Position was saved!'});
					ui.item.flare();
				}});
			}
		});

		// on delete
		$('a.category_delete', '#categories').on('click', function(e) {
			e.preventDefault();
			var self = $(this);

			// show confirm
			Frontend.noty({
				type: 'warning',
				text: 'Are you sure?',
				buttons: [{text: 'Yes', onClick: function($noty) {
					$noty.close();

					// do ajax
					Frontend.ajax({type: 'post', data: 'id=' + self.data('id'), url: 'categories/delete', success: function(data){
						// send messages
						Frontend.noty({type: 'success', text: 'Category was deleted!'});
						Frontend.noty({type: 'warning', text: 'Rebuilding search index!'});

						Frontend.ajax({type: 'get', url: 'forum/rebuild', success: function(){
							// send messages
							Frontend.noty({type: 'success', text: 'Search index rebuilt!'});

							// redirect
							Frontend.go('categories');
						}});
					}});
				}}, {text: 'No', onClick: function($noty) {
					$noty.close();
				}}]
			});
		});

	// constructor
	}, __construct = function() {
		fields();
		bind();
		intercept();
	};

	// public, yay
	return {
		init: __construct
	};
}();